package com.frame.project.service.system.config.imp;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.persistence.criteria.Predicate;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.frame.common.constant.Constants;
import com.frame.common.constant.UserConstants;
import com.frame.common.enumutil.RemoveEnum;
import com.frame.common.utils.CacheUtils;
import com.frame.common.utils.StringUtils;
import com.frame.common.utils.text.Convert;
import com.frame.framework.web.service.imp.AbstractBaseService;
import com.frame.project.domain.system.config.Config;
import com.frame.project.repository.system.config.ConfigRepository;
import com.frame.project.service.system.config.IConfigService;

/**
 * 
 * @className ：ConfigServiceImpl
 * @describe ：参数配置
 */
@Service
public class IConfigServiceImpl extends AbstractBaseService<Config> implements IConfigService {

	@Autowired
	private ConfigRepository configRepository;

	 /**
     * 项目启动时，初始化参数到缓存
     */
    @PostConstruct
    public void init()
    {
        List<Config> configsList = findAllByRs(RemoveEnum.NOT_REMOVE.getCode());
        for (Config config : configsList)
        {
            CacheUtils.put(getCacheName(), getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
    }
    
    /**
          * 分页
     */
	@Override
	public Page<Config> findByPage(Integer pageNo, Integer pageSize, Config config) {
		List<Sort.Order> orders = new ArrayList<>();
		orders.add(new Sort.Order(Sort.Direction.ASC, "id"));
		Sort sort = Sort.by(orders);
		Pageable pageable = PageRequest.of(pageNo, pageSize, sort);
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		Page<Config> page = configRepository.findAll((root, query, cb) ->{
			List<Predicate> list = new ArrayList<>();
			list.add(cb.and(cb.equal(root.get("removeStatus").as(Integer.class), RemoveEnum.NOT_REMOVE.getCode())));
			
			if(StringUtils.isNotBlank(config.getConfigName())) {
				list.add(cb.and(cb.like(root.get("configName").as(String.class), config.getConfigName())));
			}
			
			if(StringUtils.isNotBlank(config.getConfigType())) {
				list.add(cb.and(cb.equal(root.get("configType").as(String.class), config.getConfigType())));
			}
			
			if(StringUtils.isNotBlank(config.getConfigKey())) {
				list.add(cb.and(cb.like(root.get("configKey").as(String.class), config.getConfigKey())));
			}
			
			Map<String, Object> params = config.getParams();
			if(!params.isEmpty()) {
				String beginTime = (String) params.get("beginTime");
				String endTime = (String) params.get("endTime");
				if(StringUtils.isNotBlank(beginTime)) {
					try {
						list.add(cb.and(cb.greaterThanOrEqualTo(root.get("createTime"), sdf.parse(beginTime))));
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(StringUtils.isNotBlank(endTime)) {
					try {
						list.add(cb.and(cb.lessThanOrEqualTo(root.get("createTime"), sdf.parse(endTime))));
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			
			Predicate[] p = new Predicate[list.size()];
			return cb.and(list.toArray(p));
		},pageable);
		
		return page;
	}
    
	 /**
	  * 新增参数配置
     * 
     * @param config 参数配置信息
     */
    @Override
    public void insertConfig(Config config)
    {
        add(config);
        
        CacheUtils.put(getCacheName(), getCacheKey(config.getConfigKey()), config.getConfigValue());
    }
    
    /**
          * 修改参数配置
     * 
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public void updateConfig(Config config)
    {
    	Config c = findById(config.getId());
    	c.setConfigName(config.getConfigName());
    	c.setConfigKey(config.getConfigKey());
    	c.setConfigValue(config.getConfigValue());
    	c.setConfigType(config.getConfigType());
    	c.setRemark(config.getRemark());
    	
        modify(c);
        
        CacheUtils.put(getCacheName(), getCacheKey(config.getConfigKey()), config.getConfigValue());
    }
	
    /**
	 * 根据ID删除
	 * @param id
	 */
    @Override
    public void deleteConfigById(Long id) {
    	Config config = findById(id);
    	remove(id);
    	
    	CacheUtils.remove(getCacheName(), getCacheKey(config.getConfigKey()));
    }
    
    /**
     * 批量删除参数配置对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public void deleteConfigByIds(String ids)
    {
        Long[] strArray = Convert.toLongArray(ids);
        for(Long id : strArray) {
        	delete(id);
        }

        CacheUtils.removeAll(getCacheName());
    }
    
    /**
          * 清空缓存数据
     */
    @Override
    public void clearCache()
    {
        CacheUtils.removeAll(getCacheName());
    }
    
    /**
          * 根据键名查询参数配置信息
     * 
     * @param configKey 参数名称
     * @return 参数键值
     */
    @Override
    public String selectConfigByKey(String configKey)
    {
        String configValue = Convert.toStr(CacheUtils.get(getCacheName(), getCacheKey(configKey)));
        if (StringUtils.isNotEmpty(configValue))
        {
            return configValue;
        }
        Config retConfig = configRepository.findByConfigKey(configKey);
        if (StringUtils.isNotNull(retConfig))
        {
            CacheUtils.put(getCacheName(), getCacheKey(configKey), retConfig.getConfigValue());
            return retConfig.getConfigValue();
        }
        return StringUtils.EMPTY;
    }
    
    /**
     * 校验参数键名是否唯一
     * 
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public String checkConfigKeyUnique(Config config)
    {
        Long configId = StringUtils.isNull(config.getId()) ? -1L : config.getId();
        Config info = configRepository.findByConfigKey(config.getConfigKey());
        if (StringUtils.isNotNull(info) && info.getId() != configId){
            return UserConstants.CONFIG_KEY_NOT_UNIQUE;
        }
        return UserConstants.CONFIG_KEY_UNIQUE;
    }
    
    
    /**
     * 获取cache name
     * 
     * @return 缓存名
     */
    private String getCacheName()
    {
        return Constants.SYS_CONFIG_CACHE;
    }

    /**
     * 设置cache key
     * 
     * @param configKey 参数键
     * @return 缓存键key
     */
    private String getCacheKey(String configKey)
    {
        return Constants.SYS_CONFIG_KEY + configKey;
    }
}
